package com.example.quartzdemo.util;

import com.example.quartzdemo.annotation.QuartzTaskClass;
import com.example.quartzdemo.annotation.QuartzTaskMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.SystemPropertyUtils;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;

@Component
public class TaskScanner {

    @Autowired
    private ApplicationContext applicationContext;

    public List<Map<String, String>> getAvailableTasks() {
        List<Map<String, String>> tasks = new ArrayList<>();
        String basePackage = "com.example.quartzdemo";

        try {
            // 获取资源解析器
            ResourcePatternResolver resourcePatternResolver = applicationContext;
            MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);

            // 构建扫描路径
            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage)) +
                    "/**/*.class";

            // 扫描类资源
            Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);

            for (Resource resource : resources) {
                if (resource.isReadable()) {
                    MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
                    String className = metadataReader.getClassMetadata().getClassName();

                    // 检查类是否有 @QuartzTaskClass 注解
                    if (metadataReader.getAnnotationMetadata().hasAnnotation(QuartzTaskClass.class.getName())) {
                        processClass(Class.forName(className), tasks);
                    }
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException("Failed to scan tasks", e);
        }
        return tasks;
    }

    private void processClass(Class<?> clazz, List<Map<String, String>> tasks) {
        QuartzTaskClass classAnno = clazz.getAnnotation(QuartzTaskClass.class);
        String className = clazz.getName();
        String classLabel = classAnno.name();

        for (Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(QuartzTaskMethod.class)) {
                QuartzTaskMethod methodAnno = method.getAnnotation(QuartzTaskMethod.class);
                String methodName = method.getName();
                String methodLabel = methodAnno.name();

                Map<String, String> item = new HashMap<>();
                item.put("className", className);
                item.put("classLabel", classLabel);
                item.put("methodName", methodName);
                item.put("methodLabel", methodLabel);
                tasks.add(item);
            }
        }
    }
}